/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.pool2.impl;

import java.util.Set;

/**
 * Java中用于管理对象池的接口，它提供了一些方法来获取、释放和监控对象池的状态
 */
public interface GenericObjectPoolMXBean {

    // 当对象池没有空闲对象时，新的获取对象的请求是否阻塞
    // 当 blockWhenExhausted 设置为 true  时，如果对象池中没有可用对象，客户端线程将会被阻塞，直到有对象可用为止。这种模式被称为“阻塞模式”（Blocking Mode）。
    // 当 blockWhenExhausted 设置为 false 时，如果对象池中没有可用对象，客户端线程将不会等待，而是直接抛出异常，表示无法从对象池中获取到对象。这种模式被称为“非阻塞模式”（Non-Blocking Mode）。
    // 通过设置 blockWhenExhausted 的值，可以根据实际需求来选择合适的线程处理方式。
    // 在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，可以将 blockWhenExhausted 设置为 false，
    // 让客户端线程在无法获取到对象时立即抛出异常。而在低并发场景下，为了提高系统吞吐量，可以将 blockWhenExhausted 设置为 true，让客户端线程在无法获取到对象时进行阻塞等待。
    boolean getBlockWhenExhausted();


    // 当前已经从对象池中借用出去的对象数量。
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要选择一个或多个空闲对象进行回收，以便为新的请求腾出空间。此时，会将借用出去的对象数量加一，并将该对象标记为已借用状态。
    // 通过维护 borrowedCount 变量的值，可以实时了解当前已经借用出去的对象数量。这对于监控和管理对象池的状态非常重要，可以帮助开发人员及时发现和解决潜在的问题，例如对象池中的资源被过度使用或滥用等。
    // borrowedCount 只是一个内部计数器，它并不直接暴露给外部使用。在使用 BaseGenericObjectPool 时，可以通过调用相应的方法来获取对象池的可用对象数量、已借用对象数量等信息，而不需要直接操作 borrowedCount 变量。
    long getBorrowedCount();


    long getCreatedCount();


    String getCreationStackTrace();


    long getDestroyedByBorrowValidationCount();


    long getDestroyedByEvictorCount();


    long getDestroyedCount();


    String getFactoryType();


    long getMeanActiveTimeMillis();


    long getReturnedCount();

    // 表示对象池中的对象分配策略
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要选择一个或多个空闲对象进行回收，以便为新的请求腾出空间。fairness 用于控制这种对象分配策略。
    // "FIFO"（先进先出）：按照对象被创建的顺序进行分配，即最早创建的对象最先被分配出去。
    // "LIFO"（后进先出）：按照对象被创建的逆序进行分配，即最后创建的对象最先被分配出去。
    // "RANDOM"（随机）：随机选择一个可用的对象进行分配。
    // 通过设置 fairness 的值，可以根据实际需求来选择合适的线程处理方式。
    // 在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，可以将 fairness 设置为 "FIFO" 或 "LIFO"，以便及时回收不再使用的对象；
    // 在低并发场景下，为了提高系统吞吐量，可以将 fairness 设置为 "RANDOM"，减少回收操作的次数和时间。
    boolean getFairness();


    // 表示对象池中的对象分配策略。
    boolean getLifo();


    /**
     * 废弃对象跟踪的其他配置属性。
     */
    boolean getLogAbandoned();

    // 线程安全的、原子引用（AtomicReference），它用于存储 maxBorrowWaitDuration 的值。
    // maxBorrowWaitDuration 表示在对象池中没有可用对象时，客户端等待获取对象的最大时间。
    // 当有多个线程同时尝试从对象池中借用对象时，这个值可以防止过多的线程长时间阻塞在等待队列上

    // maxBorrowWaitDuration 的值为一个 Duration 类型的对象，表示等待的最长时间。
    // 当一个线程尝试从对象池中借用对象时，如果对象池为空，线程会进入等待队列。maxBorrowWaitDuration 用于限制线程在等待队列中的等待时间。
    // 当等待时间超过 maxBorrowWaitDuration 时，线程将抛出异常，表示无法从对象池中获取到对象。
    long getMaxBorrowWaitTimeMillis();


    /**
     * 最大空闲连接数
     */
    int getMaxIdle();


    // 最大连接数,默认值
    int getMaxTotal();


    // 当连接池资源用尽后，调用者获取连接时的最大等待时间。
    // 表示在对象池中没有可用对象时，客户端等待获取对象的最大时间。当有多个线程同时尝试从对象池中借用对象时，这个值可以防止过多的线程长时间阻塞在等待队列上。
    // maxWaitDuration 的值为一个 Duration 类型的对象，表示等待的最长时间。当一个线程尝试从对象池中借用对象时，
    // 如果对象池为空，线程会进入等待队列。maxWaitDuration 用于限制线程在等待队列中的等待时间。
    // 当等待时间超过 maxWaitDuration 时，线程将抛出异常，表示无法从对象池中获取到对象。
    // 通过设置 maxWaitDuration 的值，可以根据实际需求来选择合适的线程处理方式。
    // 在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，可以将 maxWaitDuration 设置为一个较短的时间，
    // 让客户端线程在无法获取到对象时立即抛出异常。而在低并发场景下，为了提高系统吞吐量，可以将 maxWaitDuration 设置为一个较长的时间，让客户端线程在无法获取到对象时进行阻塞等待。
    long getMaxWaitMillis();



    long getMeanBorrowWaitTimeMillis();

    // Getters for monitoring attributes


    long getMeanIdleTimeMillis();


    // 表示对象池中空闲对象的最小可回收时长
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要选择一个或多个空闲对象进行回收，以便为新的请求腾出空间。minEvictableIdleDuration 用于控制这种回收过程。
    // minEvictableIdleDuration 的值为一个 Duration 类型的对象，表示空闲对象的最小可回收时长。当一个空闲对象在对象池中保持空闲状态的时间超过了这个时长，那么这个对象就可以被回收。
    // 通过设置 minEvictableIdleDuration 的值，可以根据实际需求来选择合适的线程处理方式。在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，
    // 可以将 minEvictableIdleDuration 设置为一个较短的时间，让空闲对象尽快被回收。
    // 而在低并发场景下，为了提高系统吞吐量，可以将 minEvictableIdleDuration 设置为一个较长的时间，让空闲对象在对象池中保持较长时间的空闲状态
    long getMinEvictableIdleTimeMillis();

    /**
     * 最小空闲连接数
     */
    int getMinIdle();

    /**
     * 对象活跃数
     */
    int getNumActive();


    /**
     * 空闲对象数
     */
    int getNumIdle();

    // 表示每次回收空闲对象时需要进行的测试次数。 默认值3
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要选择一个或多个空闲对象进行回收，以便为新的请求腾出空间。numTestsPerEvictionRun 用于控制这种回收过程。
    // numTestsPerEvictionRun 的值为一个整数，表示每次回收空闲对象时需要进行的测试次数。在进行回收操作时，会从对象池中选择若干个空闲对象进行测试，
    // 以确定哪些对象可以被回收。测试的方式可以是随机选择、轮询等。
    // 通过设置 numTestsPerEvictionRun 的值，可以根据实际需求来选择合适的线程处理方式。
    // 在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，可以将 numTestsPerEvictionRun 设置为较小的值，减少回收操作的次数和时间。而在低并发场景下，为了提高系统吞吐量，
    // 可以将 numTestsPerEvictionRun 设置为较大的值，增加回收操作的次数和时间，以提高资源利用率。
    int getNumTestsPerEvictionRun();



    int getNumWaiters();


    boolean getRemoveAbandonedOnBorrow();


    boolean getRemoveAbandonedOnMaintenance();


    int getRemoveAbandonedTimeout();



    // 表示在借用对象时是否进行测试。默认值false
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要选择一个或多个空闲对象进行回收，以便为新的请求腾出空间。testOnBorrow 用于控制这种借用过程。
    // 如果设置为 true，则在借用对象时会对对象进行测试，以确定该对象是否可以继续被使用；
    // 如果设置为 false，则不会进行测试。
    // 通过设置 testOnBorrow 的值，可以根据实际需求来选择合适的线程处理方式。在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，
    // 可以将 testOnBorrow 设置为 true，以便及时回收不再使用的对象；而在低并发场景下，为了提高系统吞吐量，可以将 testOnBorrow 设置为 false，减少回收操作的次数和时间。
    boolean getTestOnBorrow();

    // Getters for abandoned object removal configuration


    // 表示在创建对象时是否进行测试. 默认值false
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要创建一个新的对象来满足请求
    // 如果设置为 true，则在创建对象时会对对象进行测试，以确定该对象是否可以继续被使用；
    // 如果设置为 false，则不会进行测试。
    // 通过设置 testOnCreate 的值，可以根据实际需求来选择合适的线程处理方式。在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，
    // 可以将 testOnCreate 设置为 true，以便及时回收不再使用的对象；而在低并发场景下，为了提高系统吞吐量，可以将 testOnCreate 设置为 false，减少回收操作的次数和时间。
    boolean getTestOnCreate();

    // 表示在对象被归还到对象池时是否进行测试。 默认值false
    // 当一个对象被借用后使用完毕，需要将其归还到对象池中。testOnReturn 用于控制这种归还过程。
    // 如果设置为 true，则在对象被归还到对象池时会对对象进行测试，以确定该对象是否可以继续被使用
    // 如果设置为 false，则不会进行测试
    // 通过设置 testOnReturn 的值，可以根据实际需求来选择合适的线程处理方式。在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，
    // 可以将 testOnReturn 设置为 true，以便及时回收不再使用的对象；而在低并发场景下，为了提高系统吞吐量，可以将 testOnReturn 设置为 false，减少回收操作的次数和时间。
    boolean getTestOnReturn();

    // 在空闲时是否对对象池中的对象进行测试
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要选择一个或多个空闲对象进行回收，以便为新的请求腾出空间。testWhileIdle 用于控制这种回收过程。
    // 如果设置为 true，则在空闲时会对对象池中的对象进行测试，以确定哪些对象可以被回收
    // 如果设置为 false，则不会进行测试。
    // 通过设置 testWhileIdle 的值，可以根据实际需求来选择合适的线程处理方式。
    // 在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，可以将 testWhileIdle 设置为 true，以便及时回收不再使用的对象；
    // 在低并发场景下，为了提高系统吞吐量，可以将 testWhileIdle 设置为 false，减少回收操作的次数和时间
    boolean getTestWhileIdle();


    // 表示两次回收操作之间的时间间隔。
    // 当有新的请求需要借用对象时，如果对象池中的对象数量已经达到了最大值，那么就需要选择一个或多个空闲对象进行回收，以便为新的请求腾出空间durationBetweenEvictionRuns 用于控制这种回收过程。
    // durationBetweenEvictionRuns 的值为一个 Duration 类型的对象，表示两次回收操作之间的时间间隔。在进行回收操作后，会等待指定的时间间隔后再次进行回收操作。
    // 通过设置 durationBetweenEvictionRuns 的值，可以根据实际需求来选择合适的线程处理方式。
    // 在高并发场景下，为了避免过多的线程长时间阻塞在等待队列上，可以将 durationBetweenEvictionRuns 设置为较短的时间，减少回收操作的次数和时间。
    // 在低并发场景下，为了提高系统吞吐量，可以将 durationBetweenEvictionRuns 设置为较长的时间，增加回收操作的次数和时间，以提高资源利用率。
    long getTimeBetweenEvictionRunsMillis();


    /**
     * 废弃对象跟踪的其他配置属性。
     */
    boolean isAbandonedConfig();


    // 表示对象池是否已经关闭
    // 在 BaseGenericObjectPool 中，当对象池不再需要使用时，可以调用 close() 方法来关闭对象池。当对象池被关闭后，不能再向其中添加新的对象，也不能再从中借用或归还对象。此时，closed 变量的值会被设置为 true。
    // 需要注意的是，一旦对象池被关闭，就不能再重新打开或恢复其功能。因此，在使用对象池时，应该谨慎地控制其生命周期，并在适当的时候调用 close() 方法来释放资源。
    boolean isClosed();


    Set<DefaultPooledObjectInfo> listAllObjects();
}
